package com.ruoyi.biz;

import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.test.context.support.WithSecurityContextFactory;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class MockLoginUserSecurityContextFactory implements WithSecurityContextFactory<MockLoginUser> {
    @Override
    public SecurityContext createSecurityContext(MockLoginUser loginUser) {
        String username = StringUtils.hasLength(loginUser.username()) ? loginUser
                .username() : loginUser.value();
        if (username == null) {
            throw new IllegalArgumentException(loginUser
                    + " cannot have null username on both username and value properites");
        }

        List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
        for (String authority : loginUser.authorities()) {
            grantedAuthorities.add(new SimpleGrantedAuthority(authority));
        }

        if (grantedAuthorities.isEmpty()) {
            for (String role : loginUser.roles()) {
                if (role.startsWith("ROLE_")) {
                    throw new IllegalArgumentException("roles cannot start with ROLE_ Got "
                            + role);
                }
                grantedAuthorities.add(new SimpleGrantedAuthority("ROLE_" + role));
            }
        } else if (!(loginUser.roles().length == 1 && "USER".equals(loginUser.roles()[0]))) {
            throw new IllegalStateException("You cannot define roles attribute "+ Arrays.asList(loginUser.roles())+" with authorities attribute "+ Arrays.asList(loginUser.authorities()));
        }

        LoginUser principal = new LoginUser();
        Long userId = 1L;
        SysUser sysUser = new SysUser();
        sysUser.setUserId(userId);
        sysUser.setPassword(loginUser.password());
        sysUser.setUserName(username);
        sysUser.setDeptId(loginUser.deptId());
        principal.setUserId(userId);
        principal.setUser(sysUser);
        principal.setToken("token");

        Authentication auth = new UsernamePasswordAuthenticationToken(principal, sysUser.getPassword(), grantedAuthorities);
        SecurityContext context = SecurityContextHolder.createEmptyContext();
        context.setAuthentication(auth);
        return context;
    }
}
